﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
//非类型模板参数：
//看名字就能懂，非类型模板参数就是在模板中传递的不表示类型的参数，
//在C++20之前，非类型模板参数通常只能接收一些固定类型：
//如：整形（int，size_t，bool，char等），枚举，指针（指向静态对象），引用（有限制）
//C++20开始，​​便开始支持：浮点数（float, double）、自定义类类型（需是字面类型）、更灵活的指针/引用
//其可以指定类中的某些常量值，也可以用来模仿类似变长数组的机制

//使用示例：
template<size_t N = 3>//类型名+变量名即可，也可赋值缺省参数
class stack
{
public:
	int arr[N];//由于N是常量（和宏类似，但模板能根据传的值来实例化类）
};
//缺省参数实例化
void test1()
{
	stack<> s;//使用缺省参数时也要加'<>',但C++后续也支持不加的版本，不过还是建议写加的版本，方便兼容
	int sz = sizeof(s.arr) / sizeof(s.arr[0]);
	cout << sz << endl;//3\n->可以直接sizeof计算成员中定长数组的大小
	for (int i = 0; i < sz; ++i)
	{
		cout << s.arr[i] << " ";//-858993460 -858993460 -858993460->数组中的数据并未初始化
	}
}
//传参实例化
void test2()
{
	stack<10> s;
	int sz = sizeof(s.arr) / sizeof(s.arr[0]);
	cout << sz << endl;//10\n
}

//template<double N = 3>//报错：不能传非整形家族的非类型模板参数
//class my
//{
//public:
//	int arr[N];
//};
template<class T, size_t N1, bool N2 = 2, char N3 = 'a'>//整形家族都可以传，一个模板也可以传多个非类型模板参数
class dzh
{
public:
	T arr[N1 + N2 + N3];//由于N是常量（和宏类似，但模板能根据传的值来实例化类）
};
void test3()
{
	dzh<int, 10, 20, 30> s;
	int sz = sizeof(s.arr) / sizeof(s.arr[0]);
	cout << sz << endl;//41\n->bool类型传20，实际用1进行计算
}

int main()
{
	//test1();
	//test2();
	test3();
	return 0;
}